home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.06 Jun 90 / XCMD Source / ParseCommands.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-05  |  10.4 KB  |  547 lines  |  [TEXT/KAHL]

  1. /********************************/
  2. /* File: ParseCommands.c        */
  3. /*                                */
  4. /* Parse commands coming in from*/
  5. /* Hypercard.                    */
  6. /*                                */
  7. /* Once the object is parsed, it*/
  8. /* is added to the draw list for*/
  9. /* the window.                    */
  10. /*                                 */
  11. /* Eventually need to match     */
  12. /* multiple tokens so that we     */
  13. /* can have parameters such as:    */
  14. /* BOLD&ITALIC&OUTLINE            */
  15. /* ----------------------------    */
  16. /* © 1989 Donald Koscheka        */
  17. /* All Rights Reserved            */
  18. /********************************/
  19.  
  20. #include    "DrawUtils.h"
  21.  
  22. #define    automatic            /* fun with the stack */
  23.  
  24.  
  25. short    strNComp( s1, s2, len )
  26.     char    *s1;
  27.     char    *s2;
  28.     long    len;
  29. /*************************
  30. *
  31. *************************/
  32. {
  33.     short    indx;
  34.     short    match = 1;
  35.     
  36.     for( indx = 1; indx <= len; indx++ )
  37.         if( *s1++ != *s2++ ){
  38.             match = 0;
  39.             break;
  40.         }
  41.     return( match );
  42. }
  43.  
  44.  
  45. long matchToken( buf, tabl )
  46.     Handle    buf;
  47.     short    tabl;
  48. /*******************************
  49. * given an input buffer and the resource 
  50. * id of the parse table, return 
  51. * the token that represents the input
  52. * string.
  53. *
  54. * A token of 0 is returned if no
  55. * match is found.  This way, you
  56. * can use the first item in the list
  57. * as the default item!
  58. *
  59. * The symbol table should have the 
  60. * format:
  61. *
  62. *    <string>, <token>
  63. * where string mathces to the input
  64. * string and token is that value for 
  65. * a given match.
  66. *******************************/
  67. {
  68.     char    *bp;            /*** pointer to input strings            ***/
  69.     Handle    strH;            /*** handle to parse strings resource    ***/
  70.     long    token     = 0;    /*** return the default if no match        ***/
  71.     short    indx    = 0;
  72.     short    theID;
  73.     ResType    theType;    
  74.     short    done = 0;
  75.     long    len;
  76.     char    theNum[31];    
  77.     char    *np;
  78.     char    theName[256];
  79.     char    theString[256];
  80.         
  81.     bp = *buf;
  82.     
  83.     /*** Do the comparison in upper case     ***/
  84.     /*** ??? NEED THAT TOUPPER MACRO        ***/
  85. /*    while( *bp ){
  86.         *bp = toupper( *bp );
  87.         bp++;
  88.     }
  89. */    
  90.     
  91.     strH     = GetResource( STRING_TYPE, tabl );
  92.     
  93.     if( strH ){
  94.         
  95.         GetResInfo( strH, &theID, &theType, &theName );
  96.         
  97.         /*** compare the string to the allowable tokens ***/
  98.         indx    = 1 ;
  99.         
  100.         while( !done ){
  101.             theString[0] = '\0';
  102.             GetIndString( &theString, tabl, indx );
  103.             
  104.             if( theString[0] == '\0' ){    /* no strings matched the input     */
  105.                 done = 1;
  106.             }
  107.             else{                        /* attempt to match to current str    */
  108.                 
  109.                 PtoCstr( (char *)&theString );
  110.                 
  111.                 len = 0;
  112.                 
  113.                 bp = theString;
  114.                 while ( *bp != ',' ){
  115.                     bp++;
  116.                     len++;
  117.                 }
  118.             
  119.                 if( strncmp( *buf, (char *)theString, len ) == 0){
  120.                     /* have a match so extract the token    */                    
  121.                     
  122.                     /*** move past any garbage in the string ***/
  123.                     while( (*bp < '0' || *bp > '9') && *bp != '-')
  124.                         bp++;
  125.                     
  126.                     /*** now copy what bp points to into a     ***/
  127.                     /*** a pascal style string                ***/
  128.                     
  129.                     theNum[0] = '\0';
  130.                     np = &theNum[1];
  131.                     
  132.                     while( *bp >= '0' && *bp <= '9' ){
  133.                         theNum[0]++;
  134.                         *np++ = *bp++;
  135.                     }
  136.                     
  137.                     /*** np is a valid p-string                ***/
  138.                     StringToNum( theNum, &token );
  139.                     done = 1;
  140.                 }
  141.                 else
  142.                     indx++;
  143.             }
  144.         }
  145.     }
  146.     return( token );
  147. }
  148.  
  149.  
  150. long    parseNum( bp )
  151.             char    *bp;
  152. /***********************
  153. * parse the data stream 
  154. * and return a numeric 
  155. * value.  The stream is null
  156. * terminated.
  157. *
  158. ***********************/
  159. {
  160.     long    num = 0;
  161.     
  162.     char    theString[256];
  163.     short    done = 0;
  164.     char    *ps;
  165.         
  166.     /*** move the input pointer until we're looking at a number    ***/
  167.     while( *bp && ( *bp < '0' || *bp > '9' ) && *bp != '-' )
  168.         bp++;
  169.     
  170.     /*** copy the data into a pascal string     ***/
  171.     ps    = theString;
  172.     ps++;
  173.     
  174.     while( *bp >= '0' && *bp <= '9' )
  175.         *ps++ = *bp++;
  176.     
  177.     /*** moved one past the output so try this    ***/
  178.     theString[0] = (char)( ps - theString -1  );    
  179.     StringToNum( theString, &num );
  180.     
  181.     return( num );    
  182. }
  183.  
  184.  
  185. void    parsefloat( bp, outp )
  186.             char    *bp;
  187.             char    *outp;
  188. /***********************
  189. * return the next substring
  190. * in bp that represents a 
  191. * floating number.
  192. *
  193. * accumulates a conditioned 
  194. * number string into the
  195. * output buffer.
  196. *
  197. * data gets copied into 
  198. * a pascal string.
  199. *
  200. * convert (x) to -x
  201. * eat commas in the number.
  202. ***********************/
  203. {
  204.     char    *ps = outp;
  205.     
  206.     *ps++ = '\0';
  207.     
  208.     /*** move the input pointer until we're looking at a number    ***/
  209.     while( *bp == SPACE )
  210.         bp++;
  211.     
  212.     if( *bp == '(' )    /*** for converting negatives ***/
  213.         *ps++ = '-';
  214.         
  215.     while( *bp && ( *bp < '0' || *bp > '9' ) && *bp != '-' && *bp != '.' && *bp != '+' )
  216.         bp++;
  217.     
  218.     /*** copy the data into a pascal string     ***/
  219.     while( ( *bp >= '0' && *bp <= '9' ) || *bp == '.' || *bp == '-' || *bp == ',')
  220.         if( *bp == ',' )    
  221.             *bp++;
  222.         else
  223.             *ps++ = *bp++;
  224.     
  225.     /*** moved one past the output so try this    ***/
  226.     *outp = (char)(ps - outp - 1);
  227. }
  228.  
  229.  
  230.  
  231. char    *nextToken( bp )
  232.             char    *bp;
  233. /***********************
  234. * given a pointer to an
  235. * input stream, move to the 
  236. * next token in the stream. 
  237. * Token's are delineated by
  238. * ',' or whitespace
  239. *
  240. * Assumes we are pointing to the current token
  241. * Move past the current token and the white
  242. * space that follows it.
  243. ***********************/
  244. {
  245.     /*** move past the current token    ***/
  246.     while( *bp &&(*bp != ',' && *bp != SPACE && *bp != CR && *bp != LF && *bp != TAB) )
  247.         bp++;
  248.  
  249.     /*** move past the white space to the next token    ***/
  250.     while( *bp == ',' || *bp == SPACE || *bp == CR || *bp == LF || *bp == TAB )
  251.         bp++;
  252.     
  253.     return( bp );
  254. }
  255.  
  256.  
  257. void     parseRect( buf, theRect )
  258.             Handle    buf;
  259.             Rect    *theRect;
  260. /***********************
  261. * parse the data stream 
  262. * into a rectangle
  263. ***********************/
  264. {
  265.     char    *bp;
  266.     
  267.     HLock( buf );
  268.     
  269.     bp = *buf;
  270.     theRect->top = parseNum( bp );
  271.     bp    = nextToken( bp );
  272.     
  273.     theRect->left = parseNum( bp );
  274.     bp    = nextToken( bp );
  275.     
  276.     theRect->bottom = parseNum( bp );
  277.     bp    = nextToken( bp );
  278.     
  279.     theRect->right = parseNum( bp );
  280.     bp    = nextToken( bp );
  281.     
  282.     HUnlock( buf );
  283. }
  284.     
  285.     
  286.     
  287. dataHand    Parse_Title( paramPtr )
  288.             XCmdBlockPtr     paramPtr;
  289. /*******************************
  290. * Draw a title on the screen:
  291. * command looks like this:
  292. *
  293. * params[0] == "DRAW"
  294. * params[1] == <window name>
  295. * params[2] == "TITLE"
  296. * params[3] == the string
  297. * params[4] == the bounding rect
  298. * params[5] == the font
  299. * params[6] == the size
  300. * params[7] == the style
  301. * params[8] == the justification
  302. * params[9] == color
  303. *
  304. * Defaults:
  305. *    whole screen, Geneva, 9, plain, left
  306. *
  307. * Object Format:
  308. * <rect><font><size><style><just><text>
  309. *******************************/
  310. {
  311.     Rect        theRect;
  312.     titlHand    theTitle = NIL;
  313.     titlPtr        tp;
  314.     short        theFont;
  315.     long        siz;
  316.     Handle        theText;
  317.     short        temp;
  318.     char        *fp1;
  319.     char        *fp2;
  320.     char        fontName[256];
  321.     
  322.     theTitle = (titlHand)NewHandle( sizeof( titleObj ) );
  323.     
  324.     if( theTitle ){
  325.         /*** set the defaults                ***/
  326.         tp = *theTitle;
  327.         tp->theRect.top = 0;
  328.         tp->theRect.left= 0;
  329.         tp->theRect.bottom = 100;
  330.         tp->theRect.right  = 100;
  331.         
  332.         tp->font     = 3;
  333.         tp->size     = 9;
  334.         tp->style     = 0;
  335.         tp->just     = teJustLeft;
  336.         tp->color     = blackColor;
  337.         tp->text     = NIL;
  338.         
  339.         /*** parse the parameter list        ***/    
  340.         theText = paramPtr->params[3];
  341.         HandToHand( &theText );
  342.  
  343.         HLock( theTitle );
  344.         tp = *theTitle;
  345.         tp->text = theText;
  346.         
  347.         if( paramPtr->params[4] ){
  348.             parseRect( paramPtr->params[4], &theRect );
  349.             tp->theRect.top     = theRect.top;
  350.             tp->theRect.left    = theRect.left;
  351.             tp->theRect.bottom     = theRect.bottom;
  352.             tp->theRect.right     = theRect.right;
  353.         }
  354.         
  355.         if( paramPtr->params[5] ){
  356.             siz = GetHandleSize( paramPtr->params[5] )-1;
  357.             fontName[0] = '\0';
  358.             fp1 = fontName + 1;
  359.             fp2 = *(paramPtr->params[5]);
  360.             
  361.             while( *fp2 )
  362.                 *fp1++ = *fp2++;
  363.                 
  364.             fontName[0] = (char)siz;
  365.             GetFNum( fontName, &theFont );
  366.     
  367.             tp = *theTitle;
  368.             tp->font = theFont;
  369.         }
  370.         
  371.         if( paramPtr->params[6] )
  372.             tp->size = parseNum( *(paramPtr->params[6] ) );
  373.         
  374.         if( paramPtr->params[7] ){
  375.                 temp = (short)matchToken( paramPtr->params[7], TEXT_STYLES );
  376.             tp->style = temp;
  377.         }
  378.         
  379.         if( paramPtr->params[8] ){        
  380.             temp = (short)matchToken( paramPtr->params[8], TEXT_JUSTIFICATION );
  381.             tp->just = temp;
  382.         }
  383.         
  384.         if( paramPtr->params[9] ){        
  385.             temp = (short)matchToken( paramPtr->params[9], COLORS );
  386.             tp->color = temp;
  387.         }
  388.         
  389.         HUnlock( theTitle );
  390.  
  391.         (*theTitle)->token= TITLE;
  392.     }/* if theTitle */
  393.     
  394.     return( (dataHand)theTitle );
  395. }
  396.  
  397.  
  398.  
  399. /*** consider is_white and is_number as macros! ***/
  400.  
  401. is_white( tc )
  402.     char    tc;
  403. /****************************
  404. * determine whether the character is 
  405. * white space and return the result
  406. *
  407. * Currently only accepting space
  408. * and tab as white space.
  409. ****************************/
  410. {
  411.     return( tc == SPACE || tc == TAB ); 
  412. }
  413.  
  414. is_digit( tc )
  415.     char    tc;
  416. /****************************
  417. * return true if the next character
  418. * in the input is a digit:
  419. *
  420. * should be a macro
  421. *
  422. * digit ::= 0|1|2|3|4|5|6|7|8|9
  423. ****************************/
  424. {
  425.     if( (tc >= '0' && tc <= '9')   )
  426.         return( TRUE );
  427.         
  428.     return( FALSE );
  429. }
  430.  
  431.  
  432. is_number( tp )
  433.     char    *tp;
  434. /****************************
  435. * return true if the next character
  436. * in the input is a number:
  437. *
  438. * digit ::= 0|1|2|3|4|5|6|7|8|9
  439. * sign    ::= -, (
  440. * number::= sign|digit
  441. *
  442. ****************************/
  443. {
  444.     register    tc = *tp++;
  445.     
  446.     if( (tc >= '0' && tc <= '9') || tc == '+' || tc == '(' || tc == '$' )
  447.         return( TRUE );
  448.     
  449.     if( (tc == '-' || tc == '.') && is_digit( *tp ) )
  450.         return( TRUE );
  451.         
  452.     return( FALSE );
  453. }
  454.  
  455.  
  456. char    *skip_spaces( tp )
  457.         char    *tp;
  458. /****************************
  459. * move thru the input string 
  460. * until the next character is non-
  461. * space.
  462. ****************************/
  463. {
  464.     while( *tp && (*tp == SPACE || *tp == TAB) )
  465.         tp++;
  466.         
  467.     return( tp ); 
  468. }
  469.  
  470. char    *skip_to_number( tp )
  471.         char    *tp;
  472. /****************************
  473. * move thru the input string 
  474. * until the next character is non-
  475. * space.
  476. ****************************/
  477. {
  478.     while( *tp && (*tp == SPACE || *tp == TAB || *tp == '%' || *tp == '$' ) )
  479.         tp++;
  480.         
  481.     return( tp ); 
  482. }
  483.  
  484. char    *skip_white( tp )
  485.         char    *tp;
  486. /****************************
  487. * move thru the input string 
  488. * until the next character is non-
  489. * white.
  490. ****************************/
  491. {
  492.     while( *tp && ( *tp == SPACE || *tp == TAB || *tp == CR) )
  493.         tp++;
  494.         
  495.     return( tp ); 
  496. }
  497.  
  498.  
  499. char    *skip_literal( tp )
  500.         char    *tp;
  501. /****************************
  502. * move thru the input string 
  503. * until the next character is a
  504. * space, tab, return or null.
  505. *
  506. * return the value of the pointer
  507. *
  508. ****************************/
  509. {
  510.     while( *tp && *tp != SPACE && *tp != TAB && *tp != CR  )
  511.         tp++;
  512.     
  513.     return( tp ); 
  514. }
  515.  
  516.  
  517.  
  518. short matches_literal( inp )
  519.     char    *inp;
  520. /****************************
  521. * append the given character to the
  522. * end of the handle.
  523. *
  524. * currently handles:
  525. *    NA, N/A, na, n/a
  526. ****************************/
  527. {
  528.     
  529.     if( *inp == 'N' || *inp == 'n' ){
  530.         inp++;
  531.         if( *inp == 'A' || *inp == 'a' || *inp == '/' ){
  532.             
  533.             *inp++ = '0';
  534.             
  535.             while( !is_white( *inp ) && *inp != CR && *inp != '\0' )
  536.                 *inp++ = ' ';
  537.             
  538.             return( TRUE );
  539.         }
  540.     }
  541.     
  542.     return( FALSE );
  543. }
  544.  
  545.